CSS 选择器的应用


:empty
:empty 选择器匹配没有子元素(包括文本节点)的每个元素。这里说的子元素,只计算元素结点及文本(包括空格),注释、运行指令不考虑在内。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
    <style>
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
input:empty {
background: #ccc;
}
div {
margin: 20px;
width: 200px;
height: 200px;
background: #ddd;
overflow: hidden;
}
div:empty {
background: #eee;
}
</style>

</head>
<body>
<div>我是有文本内容的 div</div>
<div>
<ul>
我是有子元素的 div
<li>sadad</li>
<li>asdsad</li>
<li>asdad</li>
<li>sads</li>
<li>sdaas</li>
</ul>
</div>
<div></div>
</body>

例子图1
如图所示,在子元素或者文本内容的时候,div 的背景颜色就会变成深灰色。
:not()
:not(selector) 选择器匹配非指定元素/选择器的每个元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
	<style>
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
input:empty {
background: #ccc;
}
div {
margin: 20px;
width: 200px;
height: 200px;
background: #ddd;
overflow: hidden;
}
div:empty {
background: #eee;
}
div :not(p) {
color: #f00;
}
</style>

</head>
<body>
<div>我是有文本内容的 div</div>
<div>
<ul>
我是有子元素的 div
<li>sadad</li>
<li>asdsad</li>
<li>asdad</li>
<li>sads</li>
<li>sdaas</li>
</ul>
<p>我是这个没有被选中的子元素 p 标签,我的字体颜色是黑色</p>
</div>
<div></div>
</body>

例子图2
如上图所示,我们可以看到,div 下面的子元素中只有 p 标签的颜色是黑色,然后我们看一下我们的样式表里面的写法 : div :not(p)
这个什么意思?
这个表示的是 选中的元素是 div 下的非 p 子元素,所以 div 下的其他子元素就会被选中,只有 p 元素不会被选中,结果就如我们图示那样。
::before 与 ::after
::before 会为当前元素创建一个子元素作为伪元素。常通过 content 属性来为一个元素添加修饰性的内容。 此元素默认为行内元素。
那应该怎么使用?
我们来上一下例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
	<style>
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
p {
margin: 20px;
}
p::before {
content: "“";
color: #f00;
font-size: 32px;
}
p::after {
content: "”";
color: #f00;
font-size: 32px;
}
</style>

</head>
<body>
<p>测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试</p>
</body>

例子图3
例子出来的效果如图所示,::before 和 ::after 伪元素可以帮助我们在元素前后增加自己想要的东西,你可以把它当作一个元素来使用,可以给它设置宽高、内容、字体、背景甚至动画等等。但是要注意一点,其他属性你可以不设,但是 content 属性是必须要有的,没有它,::before 和 ::after 伪元素等于无效。
下面我们继续看两幅图:
before
after
在图中,我们可以看到,::before 与 ::after 表现为行内元素,并且 p 元素的大小并包括了它,就如同 p 标签下的子元素一样,但是与 p 标签的真正的子元素不一样的是:你在 HTML 源代码里面找不到它的存在,但是它又确确实实地展示在页面上,所以,它叫伪元素。
说到 ::before 你可能还会想到另一个写法–> :before
这里一个双引号的写法与一个单引号的写法有什么不同?
我之前没留意到这个写法,一直用的是单引号,看到双引号的出现的时候,开始怀疑以前是不是写错了?
查了资料发现,原来单引号的写法是 CSS2 标准里面的,到了 CSS3 , CSS3 为了将伪类与伪元素区分开来,就将 :before 修改成了 ::before ,实际上你写 :before 与 ::before ,绝大部分的浏览器都能识别,但是要注意 IE8 只支持 :before 的写法,如果你的老大告诉你要兼容到 IE8 ,那你就得使用 :before 的写法了。

应用:

在项目中看到 div 被设为可编辑的这种写法被大量地应用,当前有个别的需求想要给该 div 增加类似于 input 框的 placeholder 的功能,如果不考虑语义化的情况下,在此基础上给 div 增加 placeholder 的功能,我们可以怎么做呢?这里说到了 :empty 与 ::before() 选择器,我们可以尝试用起来:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
	<style>
div {
padding: 10px;
width: 300px;
height: 100px;
border: 1px solid #000;
}
[contenteditable="true"]:empty::before {
content: "请输入文字";
color: darkgrey;
}
</style>

</head>
<body>
<div contenteditable="true"></div>
</body>

例子图4